-
Notifications
You must be signed in to change notification settings - Fork 6
Refactor InfrahubNode to avoid dynamic class creation #412
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Deploying infrahub-sdk-python with
|
Latest commit: |
55d3d84
|
Status: | ✅ Deploy successful! |
Preview URL: | https://87f88962.infrahub-sdk-python.pages.dev |
Branch Preview URL: | https://pog-avoid-dynamic-class-crea.infrahub-sdk-python.pages.dev |
Codecov ReportAttention: Patch coverage is
@@ Coverage Diff @@
## develop #412 +/- ##
===========================================
- Coverage 75.38% 75.26% -0.12%
===========================================
Files 100 100
Lines 8705 8758 +53
Branches 1691 1706 +15
===========================================
+ Hits 6562 6592 +30
- Misses 1678 1693 +15
- Partials 465 473 +8
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
infrahub_sdk/query_groups.py
Outdated
@@ -94,7 +94,7 @@ async def get_group(self, store_peers: bool = False) -> InfrahubNode | None: | |||
if not store_peers: | |||
return group | |||
|
|||
self.previous_members = group.members.peers # type: ignore[attr-defined] | |||
self.previous_members = group._relationship_cardinality_many_data["members"].peers |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this one feels wrong to me, I think we should either use the Protocol or we should add a public method to access an attribute or a relationship by its name
group.get_relationship_many(name="members").peers
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes I agree, this was mainly to highlight the typing issue. I'm a bit reluctant to add new public methods, at least until we create some reservations for what we use. I like the way pydantic has done this with model_
. Still even the code above could be a bit cleaner with a private method, alternatively we could use the option from the earlier commit where this was left as group.members.peers
but with another mypy ignore code.
cfd51de
to
0840079
Compare
This is ready for review now. I've added some private methods to get attributes or relationships as well as the |
0840079
to
55d3d84
Compare
Rebased and squashed. |
The main goal of this PR is to remove two lines:
and:
What these lines do are to create a dynamic Python class for each object we define with the SDK when we create an InfrahubNode or InfrahubNodeSync object.
The main need for the creation of a new object came from the
generate_relationship_property()
function that created a setter/getter for cardinality=one relationships on the new dynamically created class.This allowed you to override the data directly on a relationship of cardinality one at the attribute level. In pseudo code if we had a node that looked like this:
Then if we had an instance of this as an InfrahubNode object:
With the new implementation both attributes and cardinality=one relationships have both a setter and a getter, so the example above with
interface.name = "Ethernet1"
. Using the same type of logic we'd be able to add a setter to cardinality=many relationships as well, we'd only have to decide how it would work if it should add a relationship or replace all previous ones.This PR changes the way we would have to manage typing, there are a few variations we could do for this an example can be seen in the two current commits of this PR within the file query_groups.py on the line
self.previous_members = group.members.peers
the first commit only updates the rules, the second commit removes the ignore rules but could make the code a bit harder to read.Test pipeline within the Infrahub project: opsmill/infrahub#6492
One change with this is that when using a Python REPL and using
dir(my_infrahub_node_object)
the name of the attributes and relationships won't be seen as attribute objects.I'm also thinking if we should have
infrahubnode_
as a reserved prefix so that we can add public functions using that name without having to fear future conflicts.